--
-- Author: shineflag
-- Date: 2018-04-02 09:35:48
--

local skynet = require "skynet"
local socket = require "skynet.socket"
local httpd = require "http.httpd"
local sockethelper = require "http.sockethelper"
local urllib = require "http.url"
local json = require("json")
local log = require("log")
local table = table
local string = string
local port = ...
local logind 

local TAG = "SIMPLEWEB"

local address_table = {}
local action_method = {}

function decode_uri(s)
    s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)
    return s
end

function encode_uri(s)
    s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)
    return string.gsub(s, " ", "+")
end


local function response(id, ...)
	local ok, err = httpd.write_response(sockethelper.writefunc(id), ...)
	if not ok then
		if err ~= sockethelper.socket_error then
			log.d(TAG,"%s error : %s", address_table[id], err)
		end
	end
end


--router 
action_method["/login"] = function(data)
	return skynet.call(logind, "lua", "client", data)
end




local function handle_socket(id)
	-- limit request body size to 8192 (you can pass nil to unlimit)
	local code, url, method, header, body = httpd.read_request(sockethelper.readfunc(id), 8192)


	if code then
		if code ~= 200 then
			response(id, code)
		else
			local action = urllib.parse(url)

			--如何获取post数据，日后要研究
			log.d(TAG,"befor decode action[%s] body[%s]",action, body)
			local data = decode_uri(body)

			log.d(TAG,"action[%s] api[%s]",action, data)
			if data and data ~= "" then
				local f = action_method[action]
				if f then 
					local ret,c = f(data)
		           	if type(ret) ~= "string" then
	                    ret = json.encode(ret or {})
		            end
	                c = c or 200
	                log.d(TAG,"method[%s] code[%d], ret[%s]",action, c, ret)
	               	response(id, c, ret)
	            else

	            	local ret,c = "-401 not found page", -104
      				response(id, c, ret)
	   			end

	   		end

		end
	else
		if url ~= sockethelper.socket_error then
			log.d(TAG,"%s error: %s", address_table[id], url)
		end
	end
end

skynet.start(function()

	logind = skynet.uniqueservice "web/logind"
	local id = socket.listen("0.0.0.0", port)
	log.e(TAG,"Listen web port %d",port)
	socket.start(id , function(sockfd, addr)
		log.d(TAG,"sockfd[%s] connected addr[%s]",sockfd, addr)
		address_table[sockfd] = addr
		socket.start(sockfd)
		local ok,reason = xpcall(handle_socket, debug.traceback, sockfd)
        if not ok then log.d(TAG,reason) end
		socket.close(sockfd)
		address_table[sockfd] = nil
	end)

end)
